 #include <iostream>
 #include <cassert>
 #include <chrono>
 #include <thread>
 #include <atomic>
 #include <write_blf.h>

 #include "ycblf.h"

#define FRAME_COUNT 10000

 uint64_t getPosixTime() {
     auto now = std::chrono::system_clock::now();
     return std::chrono::time_point_cast<std::chrono::microseconds>(now).time_since_epoch().count();
 }

 std::atomic<bool> is_start[9];
 uint64_t time_start = 0;

 void tfn_canfd(int idx) {
     while (is_start[idx]) {
         int cnt = 0;
         while(cnt++ < FRAME_COUNT){
             CanData frame{};
             frame.channel = 1;
             frame.data_len = 64;
             frame.id = 0x55;
             frame.type_flag = CAN_EN_FD | CAN_EN_BRS | CAN_FRAME_DATA | CAN_ID_STD;//| CAN_FRAME_REMOTE; //CAN_ID_STD;
             frame.time = getPosixTime() ;
             for(int i = 0 ; i < frame.data_len ; i++) {
                 frame.data[i] = 0x55;
             }
             auto start_time = getPosixTime();
             ACBlfWriteCanFdData(frame);
             std::cout << " <" << getPosixTime() - start_time << ">" << std::endl;
             std::this_thread::sleep_for(std::chrono::microseconds(100));
         }
         is_start[idx] = false;
         printf("end write can blf\n");
     }
 }

 std::atomic<bool> is_start_flex[2];
 void tfn_flex(int idx) {
     srand(time(NULL));
     while (is_start[idx]) {
         int cnt = 0;
         while(cnt++ < FRAME_COUNT){
             FlexrayData frame{};
             frame.channel = 1;
             frame.channel_mask = 0x1;
             frame.message_id = 0x55;
             frame.message_name = "Flexray";
             frame.byte_count = 520;
             frame.data_bytes = 32;
             frame.cycle_number = 16;
             frame.tag = 5;
             frame.frame_flags = 0x2;
             frame.frame_crc = 0x0;
             frame.headerCrc1 = rand() % 2000;
             frame.headerCrc2 = 0;
             frame.time = getPosixTime() - time_start;
             frame.data.clear();
             for (int i = 0 ; i < frame.data_bytes ; i++)
                 frame.data.emplace_back(rand() % 256);
             auto start_time = getPosixTime();
             ACBlfWriteFlexrayData(frame);
             std::cout << " <" << getPosixTime() - start_time << ">" << std::endl;
             std::this_thread::sleep_for(std::chrono::microseconds(100));
         }
         is_start_flex[idx] = false;
         printf("end write flexray blf\n");
     }
 }

 int main() {
     ACStartWriteBlf("can.blf");
     time_start = getPosixTime();
     for (auto & i : is_start)
         i = true;

     std::thread tid_can[9];
     for(int i = 0 ; i < 9 ; i++)
         tid_can[i] = std::thread(tfn_canfd, i);
     std::thread tid_flex[2];
     for(int i = 0 ; i < 2 ; i++)
         tid_flex[i] = std::thread(tfn_flex, i);

     while (true) {
         int cnt = 0;
         for(int i = 0 ; i < 9 ; i++) {
             if(!is_start[i])
                 cnt++;
         }
         if (8 == cnt)
             break;
     }
     ACEndWriteBlf();
     for(int i = 0 ; i < 9 ; i++) {
         tid_can[i].join();
     }
     for (int i = 0 ; i < 2 ; i++) {
         tid_flex[i].join();
     }

     return 0;

 }
